<?php

class Model_Listing extends Ac_Model {
    const TYPE = 3;

    const STATUS_PUBLISHED = 1;
    const STATUS_STARTED = 2;
    const STATUS_DRAFT = 3;
    const STATUS_DELETED = 4;
    const STATUS_BANNED = 5;
    const STATUS_MARK_SOLD = 6;
    const STATUS_PUBLISHED_DELETED = 7;
    const STATUS_BIZ_FORM_INC = 9;

    const SOLR_EN_POS = 0;
    const SOLR_TC_POS = 1;

    const RELATED_SAME_USER = 1;
    const RELATED_SAME_LOCATION = 2;
    const RELATED_SAME_CATEGORY = 4;
    const RELATED_SAME_TITLE    = 8;
    const RELATED_EXCLUDE_SAME_USER = 16;
    const RELATED_TOP_CATEGORY = 32;

    const ORIGINAL_LANGUAGE_EN = 1;
    const ORIGINAL_LANGUAGE_TC = 2;
    const ORIGINAL_LANGUAGE_SC = 4;

    //cache __get values to avoid reworking the data
    protected $_cache_get = array();

    protected static $_collection = 'listing';
    protected $no_solr = 0;
    /**
     *
     * @var array define the requirements for this model
     */
    protected static $_requirements = array(
        //   'em'  => array('Required', 'Validator:EmailAddress'), //Email
        'ph' 	=> array('Array'), //Photo
        //'photos_tmp'  => array('Array'), //Photo
        'ca' 	=> array('Array'), //category
        'tag'	=> array('Array'),
    );
    protected static $_transcript = array(
        '_id'   => '_id',
        'tl_en' => 'title_en',
        'tl_tc' => 'title_tc',
        'tl_sc' => 'title_sc',
        'cs_en' => 'description_en',
        'cs_tc' => 'description_tc',
        'cs_sc' => 'description_sc',
        'st_en' => 'street_en',
        'st_tc' => 'street_tc',
        'st_sc' => 'street_sc',
        'at'    => 'ad_type',
        'arl2'    => 'area_l2',
        'pr'    => 'price',
        'fr'    => 'is_free',
        'ic'    => 'is_contact',
        'us'    => 'user',
        'ca'    => 'category',
        //'st'    => 'street',
        'sa'    => 'status',
        '_type' => '_type',
        'la'    => 'latitude',
        'lg'    => 'longitude',
        'ph'    => 'photos',
        'phc'   => 'photos_count',
        'nv'    => 'number_views',
        'c_dt'  => 'created_at',
        'p_dt'  => 'posted_at',
        'so'    => 'sold',
        'fpi'   => 'featured_photo_id',
        'pv'    => 'provider',
        'pvi'   => 'provider_id',
        'hua'   => 'user_agent', //$_SERVER['HTTP_USER_AGENT'] use for debuggin when the ad has a problem
        'tag'	=> 'tags',
        'rmrk'	=> 'remark',
        'c_name'	=> 'contact_name',
        'c_tel'	=> 'contact_tel',
        'c_msn'	=> 'contact_msn',
        'loc_f' => 'loc_flag',
        'cli' => 'count_likes',
        'ag'	=> 'agent',//1 agent, else not agent
    );
    
    protected $internal_language;

    public function __set($name, $arguments) {
        
        if(!empty($this->_cache_get[$name])) {
            unset($this->_cache_get[$name]);  
        };
        if ($name == 'title') {
            return parent::__set('title_' . Zend_Registry::get('current_language'), $arguments);
        } elseif ($name == 'description') {
            return parent::__set('description_' . Zend_Registry::get('current_language'), $arguments);
        } elseif ($name == 'street') {
            return parent::__set('street_' . Zend_Registry::get('current_language'), $arguments);
        } elseif ($name == 'is_free' || $name == 'fr' || $name == 'is_contact' || $name == 'ic' || $name == 'price' || $name == 'pr') {
            unset($this->fr);
            unset($this->ic);
            unset($this->price);
            $tr = static::$_transcript;
            $tr = array_flip($tr);
            $num = $tr[$name];
            parent::__set($num, $arguments);
            //var_dump($name, $arguments, $num, $this->$name);exit;
        } elseif ($name == 'posted_at') {
            parent::__set('p_dt', new MongoDate($arguments));
        } elseif ($name == 'created_at') {
            parent::__set('c_dt', new MongoDate($arguments));
        } elseif ($name == 'user') {

            if ($arguments instanceof Model_User) {
                $arguments = $arguments->_id;
            }
            return parent::__set($name, $arguments);
        } else {
            return parent::__set($name, $arguments);
        }
    }

    public function __isset($name) {
        $val = self::__get($name);
        return!empty($val) ? true : parent::__isset($name);
    }

    public function __call($name, $arguments) {
        if ($name == 'likes') {
            $limit = empty($arguments['limit']) ? 10 : $arguments['limit'];
            $list   = Model_Like::all(array('object' => $this->_id))->limit($limit);
            return $list;
        }
    } 

    public function __get($name) {
        if (!empty($this->_cache_get[$name])) {
            return $this->_cache_get[$name];
        }


        if ($name == 'title') {
            $res = parent::__get('title_' . $this->getInternalLanguage());
            /*
            if (empty($res)) {
                $res = parent::__get('title_en');
            }*/
            if (empty($res)) {
                if (parent::__get('at') == self::ORIGINAL_LANGUAGE_EN) {
                    $res = parent::__get('title_en');
                } elseif(parent::__get('at') == self::ORIGINAL_LANGUAGE_TC) {
                    $res = parent::__get('title_tc');
                } elseif(parent::__get('at') == self::ORIGINAL_LANGUAGE_SC) {
                    $res = parent::__get('title_sc');
                } else {
                    $res = parent::__get('title_sc');
                    if (empty($res)) {
                        $res = parent::__get('title_tc');
                    }
                }
            }
            $this->_cache_get[$name] = $res;
            return $res;
            // return parent::__get('title_en');
        } elseif ($name == 'title_dynamic') { 
           if($this->at == self::ORIGINAL_LANGUAGE_TC){
                $res = parent::__get('title_tc');
            } else {
                $res = parent::__get('title_en');
            }

            if (!empty($_GET['lng'])) {
                $res = parent::__get('title_' . $_GET['lng']);
            }

            $this->_cache_get[$name] = $res;
			
            return $res;
		
        } else  if ($name == 'title_original')  {
            if($this->at == self::ORIGINAL_LANGUAGE_TC){
                $res = parent::__get('title_tc');
            } elseif($this->at == self::ORIGINAL_LANGUAGE_SC){
                $res = parent::__get('title_sc');
            } else {
                $res = parent::__get('title_en');
            }
            $this->_cache_get[$name] = $res;
            return $res;
        } elseif ($name == 'title_url') {
            $res = parent::__get('title_' . $this->getInternalLanguage());
            if (empty($res)) {
                if ($this->at == self::ORIGINAL_LANGUAGE_EN) {
                    $res = parent::__get('title_en');
                } elseif($this->at == self::ORIGINAL_LANGUAGE_TC) {
                    $res = parent::__get('title_tc');
                } elseif($this->at == self::ORIGINAL_LANGUAGE_SC) {
                    $res = parent::__get('title_sc');
                } else {
                    //$res = parent::__get('title_tc');                    
                    $res = $this->title;
                }
            }
            $res = str_replace('/', ' ', $res);

            $this->_cache_get[$name] = $res;
            return $res;
        } elseif ($name == 'posted_at') {
            #return self::__get('p_dt')->sec;
            $dt = self::__get('p_dt');
            if (is_object($dt)) {
                return $dt->sec;
            } else {
                return strtotime($dt);
            }
        } elseif ($name == 'created_at') {
            #return self::__get('c_dt')->sec;
            $dt = self::__get('c_dt');
            if (is_object($dt)) {
                return $dt->sec;
            } else {
                return strtotime($dt);
            }
        } elseif ($name == 'description') {
            $res = parent::__get('description_' . $this->getInternalLanguage());
            if (empty($res)) {
                $res = parent::__get('description_en');
            }
            $this->_cache_get[$name] = $res;
            return $res;
            //return parent::__get('description_en');
        } elseif ($name == 'other') {
            $res = parent::__get('oth_' . $this->getInternalLanguage());
            if (empty($res)) {
                $res = parent::__get('oth_en');
            }
            $this->_cache_get[$name] = $res;
            return $res;
            //return parent::__get('description_en');
        } elseif ($name == 'street') {
            $res = parent::__get('street_' . $this->getInternalLanguage());
            if (empty($res)) {
                return $this->st;
            }
            $this->_cache_get[$name] = $res;
            return $res;
        } elseif ($name == 'price') {
            $res = str_replace(',', '', parent::__get('price'));
            if (!empty($res)) {
                $this->_cache_get[$name] = $res;
                return $res;
            }
            $res = parent::__get('is_free');
            if (!empty($res)) {
                $this->_cache_get[$name] = $res;
                return $res;
            }
            $res = parent::__get('is_contact');
            if (!empty($res)) {
                $this->_cache_get[$name] = $res;
                return $res;
            }
        } elseif ($name == 'category') {
            $res = $this->getCategory();
            $this->_cache_get[$name] = $res;
            return $res;
        } elseif($name == 'area_l2') {
            $id = parent::__get('area_l2');
            $res = Model_Location::find($id);
            $this->_cache_get[$name] = $res;
            return $res; 
        } elseif ($name == 'area_l1') {
            $id = parent::__get('area_l2');
            $res = Model_Location::find($id);
            $tmp = array();
            if (!empty($res)) {
                foreach ($res->getParentTree() as $loc) {
                    $tmp[] = $loc->name;
                }
            }
            $tmp = array_reverse($tmp);
            //remove the first one as it's the current one
            array_shift($tmp);
            $res = implode(', ', $tmp);
            $this->_cache_get[$name] = $res;
            return $res;
        } elseif ($name == 'photos') {
            return (array) parent::__get($name);
        } elseif ($name == 'featured_photo') {
            $photos = (array) parent::__get('photos');
            if (!empty($photos[(int) $this->fpi])) {
                return $photos[(int) $this->fpi];
            } elseif (!empty($photos[0])) {
                return $photos[0];
            }
            return '';
        } elseif ($name == 'user') {
            $id = parent::__get($name);
            $res = Model_User::find(new MongoId($id));
            $this->_cache_get[$name] = $res;
            return $res;
        } elseif ($name == 'likes') {
            $res   = Model_Like::all(array('object' => $this->_id, 'user' => array('$exists' => true)));
            $this->_cache_get[$name] = $res;
            return $res;
        } else {
            return parent::__get($name);
        }
    }

    public function __construct($data = array(), $config = array()) {
        if (empty($config['collection'])) {
            $config['collection'] = 'listing';
        }
        self::ensureIndex(array('nv' => 1));
        self::ensureIndex(array('phc' => 1));
        self::ensureIndex(array('ca' => 1));
        self::ensureIndex(array('c_dt' => 1));
        self::ensureIndex(array('sa' => 1));
        self::ensureIndex(array('ca' => 1, 'phc' => 1, 'c_dt' => -1));
        self::ensureIndex(array('ca' => 1, 'phc' => 1, 'nv' => -1));
        self::ensureIndex(array('pv' => 1, 'pvi' => 1));
        self::ensureIndex(array('_type' => 1));


        parent::__construct($data, $config);
        /*
          if ($this instanceof Model_Listing_Interface) {
          self::getInstance($data['id']);
          }
         *
         */
    }

    public function url($full_url = false, $force_lang = null, $content_lang = null) {
        $cache = Zend_Registry::get('cache');
        $current_language = Zend_Registry::get('current_language');
        $key = 'listing_url_'.$this->_id.'_'.$current_language.'_'.(empty($get['lng']) ? '' : $get['lng']).'_'.(int)$content_lang.'_'.(int)$force_lang.'_'.(int)$full_url;
        if (!$res = $cache->load($key)) {        
            $view = Zend_Registry::get('Zend_View');
            $params = array('ad' => $this);
            $get = array();
            if ($content_lang !== null) {
                $get['lng'] = $content_lang;
            }
            if(isset($get['pg'])) {
                unset($get['pg']);
            }
            $bak = $this->internal_language;
            if ($force_lang !== null) {
                $params = array_merge(array('lang' => $force_lang), $params);
                $this->internal_language = $force_lang;
            }
            
            $res = ($full_url ? 'http://' . REGULAR_DOMAIN : '') . $view->geturl('display', 'listing', $params, 'listing1', $get);
            $this->internal_language = $bak;
            $cache->save($res, $key, array(), 300);
        }

        return $res;
    }

    public static function getInstanceClassname($ids = null) {
        $class = 'Model_Listing_Regular';
        $ids = (array) $ids;
        foreach ($ids as $id) {
            $c = Model_Category::find($id);
            if (!empty($c->customization)) {
                $class = 'Model_Listing_' . ucfirst($c->customization);
            } else {
                $class = 'Model_Listing_Regular';
            }
        }
        return $class;
    }

    public static function getInstance($classname, $id) {
        if (is_array($classname)) {
            throw new Exception('I think you wnat to use getInstanceClassname. Sorry, Olivier');
        }

        //just a little tweak to put the right classname (bypass Shanty)
        $connection = Shanty_Mongo::getWriteConnection(self::$_connectionGroup);
        $db = $connection->selectDB(self::$_db);
        $mco = $db->selectCollection(self::$_collection);
        $tmp = $mco->findOne(array('_id' => new MongoId($id)));
        unset($tmp['_t']);
        $tmp['_type'] = array($classname, 'Model_Listing');
        $mco->save($tmp);
        return self::find(new MongoId($id));
    }

    public function newView() {
        if (!empty($_SERVER['HTTP_USER_AGENT']) && !preg_match('#(bot|slurp)#i', $_SERVER['HTTP_USER_AGENT'])) {
            $this->update(array('_id' => $this->_id), array('$inc' => array('nv' => 1)), array('upsert' => false));
            Model_User::update(array('_id' => $this->user->_id), array('$inc' => array('nv' => 1)), array('upsert' => false, 'multiple' => false));
            if (!empty($this->user->cid)) {
                Model_Company::update(array('_id' => $this->user->cid), array('$inc' => array('nv' => 1)), array('upsert' => false, 'multiple' => false));
            }
        }
    }

    public function preSave() {
        $this->phc = count($this->ph);
        if (empty($this->c_dt)) {
            $this->c_dt = new MongoDate(time());
        } elseif (!$this->c_dt instanceof MongoDate) {
            $this->c_dt = new MongoDate($this->c_dt);
        } elseif ($this->c_dt->sec < 0) {
            $this->c_dt = new MongoDate(time());
        }
		
        if (empty($this->p_dt)) {
            $this->p_dt = new MongoDate(time());
        }
		
        if (empty($this->at)) {
            $this->at = -1;
        }
		
        //ob_clean();echo '<pre>';var_dump($this->user_agent, $this->_id);exit;
        if (empty($this->user_agent) && empty($this->_id) && !empty($_SERVER['HTTP_USER_AGENT'])) {
            $this->user_agent = $_SERVER['HTTP_USER_AGENT'];
        }

        //Edit a new Ad
        //echo '<PRE>';
        //print_r($this);

        if (isset($this->_cleanData['sa'])) {
            if ($this->_cleanData['sa'] != $this->status) {
                //Publish
                if ($this->status == self::STATUS_PUBLISHED) {
                    $cat = $this->category;
                    $tmp = array();
                    foreach ((array) $cat as $data) {
                        $parent = $data->getParentTree();
                        foreach ((array) $parent as $k) {
                            if (in_array((string) $k->_id, $tmp)) {
                                continue;
                            }
                            $tmp[] = (string) $k->_id;
                            $k->listing_count = $k->listing_count + 1;
                            $k->save();
                        }
                    }
                }
                //Draft
                elseif ($this->status == self::STATUS_DRAFT) {
                    $cat = $this->category;
                    $tmp = array();
                    foreach ((array) $cat as $data) {
                        $parent = $data->getParentTree();
                        foreach ((array) $parent as $k) {
                            if (in_array((string) $k->_id, $tmp)) {
                                continue;
                            }
                            $tmp[] = (string) $k->_id;
                            $k->listing_count = $k->listing_count - 1;
                            $k->save();
                        }
                    }
                }
                /*
                  } else {
                  $cat = $this->category;
                  $tmp = array();
                  foreach ((array)$cat as $data) {
                  $parent = $data->getParentTree();
                  foreach ((array)$parent as $k) {
                  if (in_array((string)$k->_id, $tmp)) {
                  continue;
                  }
                  $tmp[] = (string)$k->_id;
                  $k->listing_count = $k->listing_count + 1;
                  $k->save();
                  }
                  }
                 *
                 */
            }
        }
        //print_r($this);
        //debug_print_backtrace();
        //exit;
    }

    public function postSave() {
        if (!empty($this->no_solr)) {
            return false;
        }
        $doc = $this->getSolrDocument();
        if ($doc !== false) {
            try {
                $client = Ac_Search::getClient();
                $client->addDocument($doc);
                
                //$client->commit();
                Zend_Registry::set('do_commit', 1);// any commit is now done at the end of the page loading
            } catch (Exception $e) {
                error_log('Listing has not been saved in solr: ' . $this->_id, 3, '/tmp/listing-missing-solr-' . APPLICATION_ENV . '.log');
            }
            //exit;
        }

        //clear out redis cache entries
        $redis = Zend_Registry::get('redis');
        $list = $redis->keys(APPLICATION_ENV . '-listing_*'.$this->_id.'*');
        foreach($list as $key) {
            $redis->del($key);
        }

        //if new document (post date is really recent, let's add it to the category lists
        if (true || $this->p_dt->sec > time() - 10000) { //was saved less than 10 sec ago
            foreach($this->category as $attached_cat) {
                $parent    = $attached_cat->getParent();
                $list_name = $parent->getRedisPopularKey();
                $redis->zAdd($list_name, $this->p_dt->sec, (string)$this->_id);
                $redis->zRemRangeByRank($list_name, 0, '-'.Model_Category::LISTING_POPULAR_LIMIT); //keep 5 elements in the list (0 score min, -1 score max)   
                $list_name = $parent->getRedisRecentKey();
                $redis->zAdd($list_name, $this->p_dt->sec, (string)$this->_id);
                $redis->zRemRangeByRank($list_name, 0, '-'.Model_Category::LISTING_RECENT_LIMIT); //keep 5 elements in the list (0 score min, -1 score max)   
           }
        }
    }

    public function getSolrDocument($document = null) {
        if (!$document instanceof Apache_Solr_Document) {
            $document = new Apache_Solr_Document();
        }

        $view = Zend_Registry::get('Zend_View');

        $document->id = (string) $this->_id; //or something else suitably unique
        //do some testing first
        if (empty($this->us) || empty($this->user)) {
            return false;
        }

        $document->type_obj = Model_Listing::TYPE;
        $document->type_obj_s = $this->_type;

        $document->status = empty($this->status) ? 3 : $this->status;
        $document->title = $this->title_original;
        //$document->addField('title_lang', $this->title_en);
        //$document->addField('title_lang', $this->title_tc);
        $document->description = $this->description;

        foreach ((array) $this->category as $cat) {
            foreach ((array) $cat->path as $level => $id) {
                $document->addField('category', (string) $id);
                if ($level == 0) {
                    $document->addField('category_l1', (string) $id);
                } else if ($level == 1) {
                    $document->addField('category_l2', (string) $id);
                }
                $catid = Model_Category::find($id);
                if (!empty($catid)) {
                    //$document->addField('category_name', (string) $catid->nm_en);
                    //$document->addField('category_name', (string) $catid->nm_tc);
                }
            }
        }

        foreach ((array) $this->category as $cat) {
            $document->addField('category_attached', (string) $cat->_id);
            //$document->addField('category_attached_name', (string) $cat->nm_en);
            //$document->addField('category_attached_name', (string) $cat->nm_tc);
        }

        $test_price = false;
        if (!empty($this->sp)) {
            $test_price = true;
            $document->addField('price', (int) $this->sp);
            //$document->addField('sale_price', (int) $this->sp);
        }
        if (!empty($this->rp)) {
            $test_price = true;
            $document->addField('price', (int) $this->rp);
            //$document->addField('rent_price', (int) $this->rp);
        }

        if (!$test_price) {
            $document->addField('price', (int) $this->price);
        }

        if (!empty($this->sp)) {
            $document->addField('price_sort', (int) $this->sp);
        } elseif(!empty($this->rp)) {
            $document->addField('price_sort', (int) $this->rp);
        } elseif(!empty($this->is_free)) {
            $document->addField('price_sort', 0);
        } elseif(!empty($this->is_contact)) {
            $document->addField('price_sort', 0);
        } elseif(!empty($this->price)) {
            $document->addField('price_sort', (int) $this->price);
        } else {
            $document->addField('price_sort', 0);
        }

        if (!empty($this->is_free)) {
            $document->is_free = 1;
        } elseif (!empty($this->is_contact)) {
            $document->is_contact = 1;
        }

        $document->user_id = (string) $this->us;
        //ob_clean();echo '<pre>';var_dump($this->user, $this->user->cid);exit;
        if (!empty($this->user->cid)) {
            $document->company_id = (string) $this->user->cid;
            $company = Model_Company::find($this->user->cid);
            $document->company_name = (string) $company->username;
        }
        if (!empty($this->area_l2)) {
            $document->addField('area_l1_name', (string) $this->area_l1);
            $document->addField('area_l1_name', $view->t($this->area_l1, Model_Translate::TC));
            $document->area_l1 = (string) $this->area_l2->area_l1->_id;
            $document->area_l2 = (string) $this->area_l2->_id;
            $document->addField('area_l2_name', (string) $this->area_l2->nm_en);
            $document->addField('area_l2_name', $view->t($this->area_l2->nm_en, Model_Translate::TC));
            $document->city = (int) $this->area_l2->area_l1->city;
        }
        $document->current_city = CURRENT_CITY_ID;

        //$document->views = (int) $this->number_views;
        $document->sold = (int) $this->sold;

        //Google
        $document->street = $this->street;
        $document->longitude = (double) $this->longitude;
        $document->latitude = (double) $this->latitude;
        $document->addField('url', $this->url(false, 'en'));
        $document->addField('url', $this->url(false, 'tc'));
        $document->has_image = count($this->photos) > 0;


        if (!empty($this->photos)) {
            $document->photo = $this->featured_photo;
        } else {
            $document->photo = '';
        }

        $document->username = $this->user->username;
        $document->type_account = (int) $this->user->type;

        $document->created_at = gmdate('Y-m-d\TH:i:s\Z', $this->created_at);
        if (!empty($this->updated_at)) {
            $document->updated_at = gmdate('Y-m-d\TH:i:s\Z', $this->updated_at);
        }
        if (!empty($this->posted_at)) {
            $document->posted_at = gmdate('Y-m-d\TH:i:s\Z', $this->posted_at);
        }
        //$document->rnd = rand(1, 10000);
        //echo'<pre>';
        //var_dump($document);exit;

        return $document;
    }

    public function addCategory($id) {
        $tmp = (array) $this->ca;
        //$tmp[] = new MongoId($id);
        if (!in_array($id, $tmp)) {
            $tmp[] = new MongoId($id);
        }
        $this->ca = $tmp;
    }

    public function destroyCategory() {
        $tmp = $this->ca;
        //$tmp[] = new MongoId($id);
        if (!in_array($id, $tmp)) {
            $tmp[] = $id;
        }
        $this->ca = $tmp;
    }

    public function getCategory() {
        $result = array();
        foreach ((array) $this->ca as $cat) {

            if (!empty($cat)) {
                $tmp = Model_Category::find($cat);
                if (!empty($tmp)) {
                    $result[] = $tmp;
                }
            }
        }
        return $result;
    }

    public function publish() {
        $this->status = self::STATUS_PUBLISHED;
        $this->forceSave();
    }

    public function unpublish() {
        $this->status = self::STATUS_DRAFT;
        $this->forceSave();
    }

    public function deleteListing() {
        $this->status = self::STATUS_DELETED;
        $this->forceSave();
    }

    public function renew() {
        $this->posted_at = time();
        $this->forceSave();
    }

    public function markAsSold() {
        $this->sold = self::STATUS_MARK_SOLD;
        $this->forceSave();
    }

    public function markAsUnSold() {
        unset($this->sold);
        $this->forceSave();
    }

    /*
     * NOT USED ANYMORE
     */

    private function getSql() {
        $fields = $values = array();
        //var_dump($this->export());
        foreach ($this->export() as $k => $v) {
            if (in_array($k, array('pr', 'rp', 'sp', 'tl_en', 'cs_en', 'c_dt', 'p_dt', 'ca', 'fr', 'ic', 'ds', 'st', 'ph', 'pv', 'us', 'sa'))) {
                if ($k == 'pr' || $k == 'rp' || $k == 'sp') {//price
                    if (!empty($v)) {
                        $values['price'] = $v;
                    }
                } elseif ($k == 'fr') {//free
                    $values['price'] = 'Free';
                } elseif ($k == 'ic') {//please contact
                    $values['price'] = 'Please Contact';
                } elseif ($k == 'tl_en') {//title
                    $values['title'] = $v;
                } elseif ($k == 'cs_en') {//description
                    $values['Description'] = $v;
                } elseif ($k == 'c_dt') {//createdate
                    $values['CreateDate'] = date('Y-m-d h:i:s', $v->sec);
                } elseif ($k == 'p_dt') {//postdate
                    $values['PostDate'] = date('Y-m-d h:i:s', $v->sec);
                } elseif ($k == 'ca') {//category
                    $cat = Model_Category::find($v[0]);
                    $values['CategoryId'] = str_replace(array('l', 'c', 'mc'), '', $cat->id);
                } elseif ($k == 'us') {//user
                    $cat = Model_User::find($v);
                    $values['UserId'] = $cat->id;
                } elseif ($k == 'arl2') {//district
                    $loc = Model_Location::find($v);
                    if (!empty($loc)) {
                        $values['proploc'] = $loc->id;
                    }
                } elseif ($k == 'st') {//street
                    $values['Address'] = $v;
                } elseif ($k == 'sa') {//status
                    $values['adstatusid'] = ($v == self::STATUS_PUBLISHED ? 1 : 6);
                } elseif ($k == 'ph') {//street
                    foreach ($v as $k => $photo) {
                        if ($k > 6) {
                            break;
                        }
                        if ($k + 1 == 1) {
                            $field = 'Photo';
                        } else {
                            $field = 'Photo' . ($k + 1);
                        }
                        $values[$field] = '/photo/' . $photo;

                        $old = umask(0);
                        @mkdir('/var/www/vhosts/hongkong.asiaclassified.com/httpdocs/photo/' . dirname($photo), 0777, true);
                        //copy to old site
                        copy('/var/www/vhosts/live.asiaclassified.com/ac2/shared/photos/original/' . $photo, '/var/www/vhosts/hongkong.asiaclassified.com/httpdocs/photo/' . $photo);
                        @umask($old);
                    }
                }
            }
        }
        //var_dump($values);
        if (!empty($this->id)) {
            $str = 'UPDATE ad SET';
            $to_add = '';
            foreach ($values as $k => $v) {
                $str .= $to_add . ' ' . $k . '=\'' . addslashes($v) . '\'';
                $to_add = ' ,';
            }
            $str .= ' WHERE adid = ' . $this->id . ' LIMIT 1';
        } else {
            $str = 'INSERT INTO ad ';
            $str1 = '';
            $str2 = '';
            $to_add = '';
            foreach ($values as $k => $v) {
                $str1 .= $to_add . $k;
                $str2 .= $to_add . '\'' . addslashes($v) . '\'';
                $to_add = ' ,';
            }
            $str .='(' . $str1 . ') VALUES (' . $str2 . ') ';
        }
        return $str;
    }

    public function isAuthorized($user) {
        return (!empty($user) && $user->role == Model_User::ROLE_ADMIN) || (!empty($user) && (string) $user->_id == (string) $this->user->_id);
    }

    public function getKeyword() {
        $arr = array();
        foreach ($this->category as $cat) {
            foreach ($cat->getParentTree() as $c) {
                $arr[] = $c->name;
            }
        }

        if (!empty($this->area_l2)) {
            $arr[] = $this->area_l2->name;
        }
        if (!empty($this->area_l1)) {
            $arr[] = $this->area_l1;
        }

        return $arr;
    }

    public static function getFacetedSearch(&$additionalParameters) {

    }

    public static function getSearchResultSort() {
        return array(
            'recent' => '最新',
            'rel' => '相关',
            'highest' => '价格↑',
            'lowest' => ' 价格↓',
        );
    }

    public function checkPerTypeDataSanity() {
        $count = 0;
        $missing = array();
        $to_save = array();

        //check that basic information are in (title, description, location, us, category
        if (empty($this->tl_en)) {
            $count++;
            $missing['title'][] = 'Missing english title (tl_en)';
        }

        if (empty($this->cs_en) && empty($this->pv)) {//only check if non feed. sometimes feeds don t have description
            $count++;
            $missing['content'][] = 'Missing english description (cs_en)';
        }

        if (empty($this->arl2)) {
            $count++;
            $missing['area_l2'][] = 'District is missing (ds)';
        }

        if (empty($this->_type)) {
            $count++;
            $missing['type'][] = '__type is missing (__type)';
        }

        if (empty($this->ca)) {
            $count++;
            $missing['category'][] = 'Category are missing (ca)';
        } else {
            if (!is_array($this->ca)) {
                $count++;
                $missing['category'][] = 'Category not an array (ca)';
            }//else{}
        }

        if (empty($this->c_dt)) {
            $count++;
            $missing['date'][] = 'Creation date is missing (c_dt)';
        }

        if (empty($this->p_dt)) {
            $count++;
            $missing['date'][] = 'Post date is missing (p_dt)';
        }

        if (empty($this->st)) {
            $count++;
            $missing['street'][] = 'Street is missing (st)';
        }

        //check if user exists
        $res = Model_User::one(array('_id' => $this->us));
        if (!empty($this->us) && !is_object($res)) {
            $count++;
            $missing['user'][] = 'User doesn\'t exists (us)';
        }

        //check if photo exists
        //auto fix included
        if (!empty($this->ph)) {
        	$photos = array();
        	$flag = false;
            foreach ($this->ph as $photo) {
                if (file_exists(APPLICATION_PATH . '../public/images/photo/original/' . $photo)) {
                    //$count++;
                    //$missing['photo'][] = $photo.' doesn\'t exists (ph)';
                    $photos[] = $photo;
                }else{
					$flag=true;
				}
            }

            if($flag){
				$this->ph = array_values($photos);
				$this->save();
				//echo "<pre>";var_dump($photos2);echo "</pre>";
			}
        }

        if (!empty($this->ph) && $this->phc != count($this->ph)) {
            $missing['photo'][] = 'number of photo stored is different than real number of photos (ph:' . count($this->ph) . ', phc:' . $this->phc . ')';
            $count++;
        }

//    	if(empty($this->br)){
//			$count++;
//			$missing['bedroom'][] = 'no bedroom';
//		}
//		if(empty($this->sz)){
//			$count++;
//			$missing['size'][] = 'no size';
//		}
        if (!empty($missing)) {
            $to_save['ls'] = $this->_id;
            $to_save['errors'] = $missing;
            $to_save['error_count'] = $count;
            //$this->save($to_save);
            //$error_found++;
            //return $to_save;
        }
        return $to_save;
    }

    public function getInternalLanguage() {
        if (empty($this->internal_language)) {
            if (!empty($_GET['lng'])) {
                $this->internal_language = $_GET['lng'];
            } else {
                $this->internal_language = Zend_Registry::get('current_language');
            }
        }
        return $this->internal_language;
    }

    public function findRelated($count = 6, $type = self::RELATED_SAME_USER, $options = array()) {
        $solr = Ac_Search::getClient();
        $qq = '';

        //if the only criteria is title an title is empty force false
        if (empty($this->title) && ($type == self::RELATED_SAME_TITLE)) {
            return false;
        }

        if (!empty($this->title) && ($type & self::RELATED_SAME_TITLE)) {
            $query = ' _query_:"{!dismax qf=$qf v=$qq}" ';
            $qq = $this->title;
            $qf = 'description^1.0 title^7.0';
        } else {
            $query = '*:*';
        }

        $additionalParameters = array();
        $fq = '';

        if ($type & self::RELATED_SAME_CATEGORY) {
            foreach ($this->category as $cat) {
                $fq .= ' +category:' . (string) $cat->_id;
                break;
            }
        }

        if ($type & self::RELATED_TOP_CATEGORY) {
            foreach ($this->category as $cat) {
                foreach($cat->getParentTree() as $par) {
                    $fq .= ' +category:' . (string) $par->_id;
                    break;
                }
            }
        }

        if ($type & self::RELATED_SAME_LOCATION) {
            if (!empty($this->area_l2) && !empty($this->area_l2)) {
                $fq .= ' +area_l2:' . (string) $this->area_l2->_id;
            }
        }

        if ($type & self::RELATED_SAME_USER) {
            $fq .= ' +user_id:' . (string) $this->user->_id;
        } else {
			if (($type == self::RELATED_TOP_CATEGORY) || ($type == self::RELATED_SAME_CATEGORY)){
				foreach ($this->category as $cat) {
					//print_r($cat->customization);
                	if($cat->customization != "job"){
						$fq .= ' +has_image:1 ';
					}
                	break;
            	}
			
			}else{
            	$fq .= ' +has_image:1 ';
			}
        }
        
        if ($type & self::RELATED_EXCLUDE_SAME_USER) {
            $fq .= ' -user_id:' . (string) $this->user->_id;
        }        

        $fq .= ' +status:1 +type_obj_s:Model_Listing -sold:6';
        $additionalParameters['fq'] = $fq;
        if (!empty($qq)) {
            $additionalParameters['qq'] = $qq;
        }
        if (!empty($qf)) {
            $additionalParameters['qf'] = $qf;
        }
        $additionalParameters['sort'] = 'random_' . rand(1, 10000) . ' desc';

        //var_dump($query, $additionalParameters);exit;
        $list = $solr->search($query, 1, $count, $additionalParameters);
        //echo '<pre style="clear:both">';var_dump('--------', $type, $query, $additionalParameters, $list->response->numFound);echo '</pre>';
        $res = new Ac_Search_Iterator($list->response->docs);
        //echo '<pre>';debug_print_backtrace();exit;
        return $res;
    }
    
    public function forceSave() 
    {
        $this->save();
        $this->postSave();
        $client = Ac_Search::getClient();
        $client->commit();
    }


    public function exportRest($compressed = false)
    {
        file_put_contents('/tmp/api-listing.txt', print_r($_SERVER, true));
        $view = Zend_Registry::get('Zend_View');
        $res = array(
            'id' => (string) $this->_id,
            'type' => 'regular',
            'status' => (string) $this->status,
            'title_sc' => (string) !empty($this->title_sc) ? html_entity_decode($this->title_sc, ENT_COMPAT, 'UTF-8') : '',
            'is_free' => (string) $this->is_free ? '1' : '0',
            'is_sold' => (string) !empty($this->sold) ? '1' : '0',
            'is_contact' => $this->is_contact ? '1' : '0',
            'url_sc' => $this->url(true, 'sc'),
            'company_id' => !empty($this->user->company->_id) ? (string)$this->user->company->_id : '',
            'company_name' => !empty($this->user->company->username) ? $this->user->company->username : '',
            'user_id' => (string) $this->user->_id,
            'username' => !empty($this->user->username) ? $this->user->username : '',
            'user_url_sc' => $this->user->url(false, 'sc'),
            'user_photo' =>  !empty($this->user->profile_picture) ? Ac_Util::getImageBaseUrl('/images/photo/original/'.$this->user->profile_picture) : '',
            'user_phone' => !empty($this->user->phone) ? $this->user->phone : '',
            'latitude' => !empty($this->latitude) ? $this->latitude : '',
            'longitude' => !empty($this->longitude) ? $this->longitude : '',
            'street' => !empty($this->street) ? $this->street : '',
            'posted_at' => (string)$this->posted_at,
            'description_sc' => !empty($this->description_sc) ? strip_tags($this->description_sc) : '',
        );

        if ($compressed) {
            unset($res['description_sc']);
        }

        if(empty($res['street']) && !empty($res['latitude'])) {
            unset($res['latitude']);
        }
        if(empty($res['street']) && !empty($res['longitude'])) {
            unset($res['longitude']);
        }


        if(!empty($this->ca)) {
            $tmp = array();
            foreach($this->category as $cat) {
                $tmp2 = array();
                foreach($cat->getParentTree() as $cat2) {
                    array_push($tmp2, $cat2->exportRest());
                }
                $tmp[] = $tmp2;
            }
            $res['category'] = $tmp;
        }

        if (!empty($this->photos)) {
            if (!$compressed) {
                $res['thumbnails'] =array();
                foreach($this->photos as $k => $photo) {
                    if (API_VERSION == 2) {
                        $img = $view->thumbnail()->scale($photo, 50, 50);
                        $size = $view->thumbnail()->getSize($img);
                        $res['thumbnails'][50][] = array('src' => $img, 'width' => $size['width'], 'height' => $size['height']);
                        $img = $view->thumbnail()->scale($photo, 130, 130);
                        $size = $view->thumbnail()->getSize($img);
                        $res['thumbnails'][130][] = array('src' => $img, 'width' => $size['width'], 'height' => $size['height']);
                        $img = $view->thumbnail()->scale($photo, 200, 200);
                        $size = $view->thumbnail()->getSize($img);
                        $res['thumbnails'][200][] = array('src' => $img, 'width' => $size['width'], 'height' => $size['height']);

                        $img = $view->thumbnail()->scale($photo, 250, 250);
                        $size = $view->thumbnail()->getSize($img);
                        $res['thumbnails'][250][] = array('src' => $img, 'width' => $size['width'], 'height' => $size['height']);
                    } else {
                        //$res['thumbnails'][130][] = $view->thumbnail()->resizeAndCrop($photo, 130, 130);
                        $res['thumbnails'][130][] = $view->thumbnail()->scale($photo, 130, 130);
                        $res['thumbnails'][200][] = $view->thumbnail()->scale($photo, 200, 200);
                        //$res['thumbnails'][200][] = $view->thumbnail()->resizeAndCrop($photo, 200, 200);
                        //$res['thumbnails'][250][] = $view->thumbnail()->resizeAndCrop($photo, 250, 250);
                        $res['thumbnails'][250][] = $view->thumbnail()->scale($photo, 250, 250);
                        $res['thumbnails'][300][] = $view->thumbnail()->resizeAndCrop($photo, 300, 300);
                        $res['thumbnails'][640][] = $view->thumbnail()->scale($photo, 640, 960);
                        $res['thumbnails'][960][] = $view->thumbnail()->scale($photo, 960, 640);                        

                    }
                    //$res['thumbnails'][300][] = $view->thumbnail()->resizeAndCrop($photo, 300, 300);
                    //$res['thumbnails'][640][] = $view->thumbnail()->scale($photo, 640, 960);
                    //$res['thumbnails'][960][] = $view->thumbnail()->scale($photo, 960, 640);
                }
                $res['photos'] =array();
                foreach($this->photos as $k => $photo) {
                    $res['photos'][] = Ac_Util::getImageBaseUrl('/images/photo/original/'.$photo);
                }
            }
            $res['featured_photo']       = (string) !empty($this->featured_photo) ? Ac_Util::getImageBaseUrl('/images/photo/original/'.$this->featured_photo) : '';
            $res['featured_photo_thumb'] = (string) !empty($this->featured_photo) ? $view->thumbnail()->resizeAndCrop($this->featured_photo, 130, 130) : '';

        } else {
                $photo = '/images/no-photo.png';
            if (!$compressed) {
                $res['photos']     = array();
                $res['photos'][]   = Ac_Util::getImageBaseUrl('/images/no-photo.png');
                $res['thumbnails'] = array();
                $res['thumbnails'][130][] = $view->thumbnail()->resizeAndCrop($photo, 130, 130);
                $res['thumbnails'][200][] = $view->thumbnail()->resizeAndCrop($photo, 200, 200);
                $res['thumbnails'][250][] = $view->thumbnail()->resizeAndCrop($photo, 250, 250);
                $res['thumbnails'][300][] = $view->thumbnail()->resizeAndCrop($photo, 300, 300);
                $res['thumbnails'][640][] = $view->thumbnail()->scale($photo, 640, 960);
                $res['thumbnails'][960][] = $view->thumbnail()->scale($photo, 960, 640);
            }
            $res['featured_photo']       = (string) Ac_Util::getImageBaseUrl($photo);
            $res['featured_photo_thumb'] = (string) $view->thumbnail()->resizeAndCrop($photo, 130, 130);
        }

        
        $price = parent::__get('price');
        /*
        if (empty($price)) {
            if($this->is_free) {
                $price = $view->t('Free');
            }
            if (empty($price)) {
                $price = $view->t('Please contact');
            }
        }
        */
        $res['price'] = (string) $price;

        if (!empty($this->district)) {
            $res['area_l2']    = (string)$this->area_l2->_id;
            $res['area_l2_sc'] = (string) $this->area_l2->nm_sc;
            $res['area_l1']    = (string)$this->area_l2->area_l1->_id;
            $res['area_l1_sc'] = (string) $this->area_l2->area_l1->nm_sc;
        }
        return $res;
    }

    public function processRestForm()
    {

        $post = $_POST;

        if (!empty($_POST['district']) && ($location = Model_Location::find($_POST['district'])) === false) {
            //echo 'category empty';exit;
            throw new Ac_Exception_MissingInformation('District is empty');
        }

        if (!empty($_POST['district'])) {
            $tmp = Model_Location::find($_POST['district']);
            if (!empty($tmp)) {
                $this->area_l2 = $tmp->_id;
            }
        }    

        if ($_POST['district'] != ONLINE_ONLY_AREA && $_POST['district'] != ENTIRE_CITY && empty($_POST['street'])) { //online only don t have addresses
            //echo 'category empty';exit;
            throw new Ac_Exception_MissingInformation('Street address is empty');
        }


        if (!empty($_POST['area_l1'])) {
            $tmp = new MongoId($_POST['area_l1']);
            if (strlen($_POST['area_l1']) == 24 && $_POST['area_l1'] == (string) $tmp) {
                $loc = Model_Location::find($_POST['area_l1']);
            } else {
                $loc = Model_Location::one(array('nm_'.$_POST['lang'] => $_POST['area_l1']));
            }

            if (empty($loc)) {
                throw new Ac_Exception_MissingInformation('Area L1 is invalid ');
            } else {
                $this->area_l1 = $loc->_id;                
            }
        }

        if (!empty($_POST['area_l2'])) {
            $tmp = new MongoId($_POST['area_l2']);
            if (strlen($_POST['area_l2']) == 24 && $_POST['area_l2'] == (string) $tmp) {
                $loc = Model_Location::find($_POST['area_l2']);
                if (empty($loc)) {
                    throw new Ac_Exception_MissingInformation('Area L2 is invalid');
                }
            } else {
                $loc = Model_Location::one(array('nm_'.$_POST['lang'] => $_POST['area_l2']));
            }

            if (!empty($loc)) {
                $this->area_l2 = $loc->_id;
            }
        }
 

        if (!empty($_POST['street'])) {
            $this->street = $_POST['street'];
        }
/*
        if (!empty($_POST['photos'])) {
            foreach($_POST['photos'] as $k => $photo) {
                if (!empty($photo)) {
                    $res = Ac_Util::downloadPhoto($this->title, $k, $photo, $this->created_at);
                    $tmp = (array) $this->photos;
                    if(!empty($res)) {
                        $tmp[] = $res;
                    }
                    $this->photos = $tmp;
                }
            }
        }
 */
        return true;
    }
    
    public function grabListings($userid)
    {
    	$m = new MongoCode('function(){
    							emit(this.us, {listing:this.obj ,count_visit:this.ct_v, visit_time:this.c_dt});
    						}'
    	);
    	$r = new MongoCode('function(key, values){
    							var result = {listing:{}};
    							for(var i=0; i<values.length; i++){
    								if(i==0){
    									
    								}
    								
    								
    							}
    						}'
    	);	
    }
    
    
}
